package admin

import (
	"context"
	"grpc.getaway.adminspro.padmins.com/internal/rpc/module/admin/adminLogic"
	"grpc.getaway.adminspro.padmins.com/internal/rpc/module/admin/roleLogic"
	"grpc.getaway.adminspro.padmins.com/internal/rpc/utils/database"
	"grpc.getaway.adminspro.padmins.com/pkg/config/businessError"
	"grpc.getaway.adminspro.padmins.com/pkg/libs/db"
	"grpc.getaway.adminspro.padmins.com/pkg/libs/utils"
	pbAdmin "grpc.getaway.adminspro.padmins.com/pkg/proto/admin"
	"strconv"
)

func (rpc *admin) AdminRoleAdd(ctx context.Context, pb *pbAdmin.AdminRoleAddReq) (*pbAdmin.AdminRoleAddResp, error) {

	if pb.AdminRole.Name == "" {
		return nil, businessError.ErrorInfoToRpcError(businessError.AdminRoleEmpty)
	}

	hasStatus := false
	for s, _ := range roleLogic.List()["status"] {
		if strconv.FormatInt(int64(pb.AdminRole.Status), 10) == s {
			hasStatus = true
		}
	}

	if hasStatus == false {
		return nil, businessError.ErrorInfoToRpcError(businessError.AdminStatusError)
	}

	roleIds := []interface{}{}
	if pb.OperaterId != 0 {
		roleIds = adminLogic.GetChildrenRoleIds(ctx, pb.OperaterId, true)
	} else {
		roleIds = adminLogic.GetChildrenRoleIdsByRoleId(ctx, int64(0), false)
	}

	if !utils.InArray(pb.AdminRole.Pid, roleIds) {
		return nil, businessError.ErrorInfoToRpcError(businessError.AdminRolePidError)
	}

	Db := database.Db.GetDefaultDb(ctx)

	has, dbErr := Db.Find("select * from admin_role where name=?", pb.AdminRole.Name)
	if dbErr != nil {
		return nil, businessError.ErrorInfoToRpcError(businessError.DbError(dbErr))
	}
	if has != nil {
		return nil, businessError.ErrorInfoToRpcError(businessError.AdminRoleExists)
	}

	id, e := Db.TransactionFunc(func(Db *db.Db) (interface{}, error) {
		date := utils.Date("Y-m-d H:i:s")
		_, dbErr := Db.Insert("admin_role", map[string]interface{}{
			"pid":         pb.AdminRole.Pid,
			"name":        pb.AdminRole.Name,
			"status":      pb.AdminRole.Status,
			"update_time": date,
			"create_time": date,
		})

		if dbErr != nil {
			return nil, businessError.ErrorInfoToRpcError(businessError.DbError(dbErr))
		}

		id, dbErr := Db.LastInsertId()

		if dbErr != nil {
			return nil, businessError.ErrorInfoToRpcError(businessError.DbError(dbErr))
		}
		ResourceIdLen := len(pb.ResourceId)
		if ResourceIdLen > 0 {
			adminRoleResourceAccess := make([]interface{}, ResourceIdLen)
			for i, resourceId := range pb.ResourceId {
				adminRoleResourceAccess[i] = map[string]interface{}{
					"role_id":     id,
					"resource_id": resourceId,
					"update_time": date,
					"create_time": date,
				}
			}

			rowCount, dbErr := Db.Insert("admin_role_resource_access", adminRoleResourceAccess)

			if dbErr != nil {
				return nil, businessError.ErrorInfoToRpcError(businessError.DbError(dbErr))
			}

			if rowCount <= 0 {
				return nil, businessError.ErrorInfoToRpcError(businessError.OperateError)
			}
		}

		return id, nil
	})

	if e != nil {
		return nil, e
	}

	return &pbAdmin.AdminRoleAddResp{
		Id: id.(int64),
	}, nil
}
